/*
 * a container class wrapper of JTabbedPane for CarShow.  This provides
 * services to the SqlClientReader() informing it which tab is active and
 * holds the requesting java.awt.Component object information returned by
 * sqlGet() and sqlPut() calls of CarShowUI
 * 
 */

package carshow;

import java.util.ArrayDeque;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * An extended version of JTabbedPane with logic added that allows for the
 * reply paths of SqlClientReader class to populate the CarShowUI forms.
 * @author W
 */
public class myJTabbedPane extends javax.swing.JTabbedPane {
    boolean connected = false;
    static boolean debug = false;
    java.awt.Component[] waitMarkers;
    int waitCntr = 0;
    java.awt.Component active_component = null;
    // linked list object to represent waiting requests queue
    ArrayDeque<java.awt.Component> aStack = new ArrayDeque();
    

    public myJTabbedPane() {
        super();
        waitMarkers = new java.awt.Component[6]; // statically sized hack...
    }
    /** convenience constructor */
    public myJTabbedPane(boolean dbg) {
        debug = dbg;
    }
    /** set the debug state of the tabbedPane */
    public static void setDebug(boolean dbg) {
        debug = dbg;
    }
    
    /** set the connected state to disconnected */
    public void disconnect() {
        connected = false;
    }
    
    /**
     * add a wait marker to the set of wait marking components.  These are
     * used by the CarShowUI and SqlClientReader classes to synchronize the
     * SQL response completion states.
     * @param c wait marking component to add
     */
    public void addMarker(java.awt.Component c) {
        waitMarkers[waitCntr++] = c;
    }

    /**
     * Gets the currently visible/active JPane
     * @return the Component (javax.swing.JPane) of the requesting CarShowUI
     * pane.  It determines which is the active pane by evaluating the Wait
     * label markers on each tab (pane) of this object.  The CarShowUI adds
     * the panes to this object during initComponents().
     */
    public java.awt.Component getActivePane() {
        java.awt.Component c = null;
        outer_loop:
        for(int i = 0; i < waitCntr; i++) {
            if ( waitMarkers[i].isVisible()) {
                java.awt.Component aparent = waitMarkers[i];
                do {
                    java.awt.Component nparent = aparent.getParent();
                    if (nparent instanceof javax.swing.JPanel) {
                        c = nparent;
                        break outer_loop;
                    }
                    else aparent = nparent;
                } while (c != null);
            }
        }
        return c;
    }
    
    /**
     * sets the current active component in the CarShowUI form where the
     * requested database information should be directed to upon receipt by
     * the SqlClientReader class.
     * @param c component marker that indicates where the DB data is to be
     * placed in the UI.
     */

    public void setActiveComponent(java.awt.Component c) {
        //System.err.print("tabbedPane: setActiveComponent: ");
        //if(c == null) {
        //    System.err.println(" NULL!!!");
        //}
        //else {
        if(c != null) {
            if(debug) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,c.getName());
            aStack.add(c);
            int sz = aStack.size();
            if(sz > 0) if(debug) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"current aStack size : "+sz);
        }

    }
    /**
     * gets the (CarShowUI) active component requesting data from the
     * DB
     * @return the active java.awt.Component object or null if not set
     */

    public java.awt.Component getActiveComponent() {
        if(aStack.isEmpty()) return null;
        else return aStack.peek();
    }
    /**
     * retrieve the stack size for recovery attempts
     */
    public int getActiveCount() {
        return aStack.size();
    }
    
    public void clearAllActiveComponents() {
        if(debug) {
            Logger.getLogger(CarShowUI.class.getName()).
                    log(Level.INFO,"clear-ALL-ActComp: request to clear");
            if(!aStack.isEmpty()) {
                Logger.getLogger(CarShowUI.class.getName()).
                log(Level.INFO,"clear-ALL-ActComp: aStack size: "+aStack.size());
                java.awt.Component c = aStack.peek();
                Logger.getLogger(CarShowUI.class.getName()).
                    log(Level.INFO,"clear-ALL-ActComp: TopOfStack comp: "+c.getName());
            }
        }
        aStack.clear();
    }
    /**
     * retrieve the top (oldest) component.  for error recovery attempt code.
     */
    public java.awt.Component getTopComponent() {
        if(aStack.isEmpty()) return null;
        else return aStack.getLast();
    }
    
    /**
     * clear the specified active component from the pending DB tasks queue.
     * if the component is not queued, there is no effect, otherwise that
     * component is removed from the container (hopefully from the head of
     * the queue) wherever it may be located in the queue.
     * @param c 
     */
    public void clearActiveComponent(java.awt.Component c) {
        if(c == null)  {
            if(debug) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clearActComp: request to clear a null");
            //if(cStack.isEmpty())
            if(debug && !aStack.isEmpty())
                Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clrActComp: cStack is not empty");
            else if(debug) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clrActComp: cStack is empty");
            return;
        }
        if(!aStack.isEmpty()) {
            if(aStack.contains(c))
                if(aStack.peek() == c) {
                    aStack.pop();
                    if(debug) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clearActComp: clear by pop");
                }
                else { 
                    aStack.remove(c);
                    Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clearActComp: WARN: clear "+c.getName()+" by REMOVE");
                }
            else Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clearActComp: ERROR: request to clear NON-Stacked comp:"+c.getName());
            if(aStack.isEmpty()) {
               if(debug) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clearActComp: cStack emptied by remove/pop of:"+c.getName());
               if(debug) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clrActComp: stack size: "+aStack.size());
               if(aStack.peek() == null && debug)
                   Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clrActComp: peek returns null");
               else if(debug) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clrActComp: peek rets "+aStack.peek().getName());
            }
            else { // stack not empty, these I want to see...
                Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clrActComp: aStack not empty");
                Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clrActComp: stack size: "+aStack.size());
                if(aStack.peek() != null)
                    Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clrActComp: peek rets: "+aStack.peek().getName());
                else if(debug) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"peek rets: null");
            }
        }
        else if(debug) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"clearActComp: cStack empty on clear rqst for:"+c.getName());
    }
    
    /**
     * Clears the contents of all wait label markers
     */
    
    public void clearWait() {
        for(java.awt.Component c : waitMarkers) {
            if (c.isEnabled() & c.isVisible()) c.setVisible(false);
        }
    }
    
    /**
     * Displays to the System.err stream what wait marker is active at this
     * time.  Debugging use only.
     */
    public void whichWaitActive() {
        for(java.awt.Component c : waitMarkers) {
            if (c.isVisible()) Logger.getLogger(CarShowUI.class.getName()).log(Level.INFO,"active wait is:"+c.getName());
        }    }
}
